"use client";

import { useEffect, useMemo } from "react";
import { PinYinStatus, Props } from "./meta";
import { Dropdown, type MenuProps } from "antd";
import { useMemoizedFn, useSafeState } from "ahooks";
import { Wrapper } from "./styles";

export default function PinYinMarker(props: Props) {
  const [isNew, setIsNew] = useSafeState(true);
  const [dropdownClassName] = useSafeState(
    `dropdown-${Date.now()}-${parseInt((Math.random() * 10000000).toString())}`,
  );
  const [mouseOpen, setMouseOpen] = useSafeState(false);
  const [itemRealIdx, setItemRealIdx] = useSafeState(props.itemIdx ?? 0);

  const open = useMemo(() => {
    return !!(mouseOpen || props.openMultiSelector);
  }, [mouseOpen, props.openMultiSelector]);
  const value = useMemo(() => {
    if (!props.data) {
      return <span>&nbsp;</span>;
    }
    const { data } = props;
    if (data?.status === PinYinStatus.UserInput) {
      return data.userInput;
    } else {
      return data?.value || data?.recommend || data?.options?.at(0);
    }
  }, [props]);
  const onPinYinMarked = useMemoizedFn(() => {
    const pinyin = props.data?.options?.at(itemRealIdx);
    if (pinyin && props.onPinYinMarked) {
      props.onPinYinMarked(pinyin);
    }
  });
  const items = useMemo<MenuProps["items"]>(
    () =>
      (props.data?.options ?? []).map((pinyin, idx) => ({
        label: (
          <span
            onClick={() => {
              setItemRealIdx(idx);
              props.onClose && props.onClose();
            }}
          >
            {pinyin}
          </span>
        ),
        key: pinyin,
      })),
    [props.data?.options],
  );

  const isPolyphonic = !!(items && items.length > 1);
  const isConfirmed = !!(
    props.data?.recommend ||
    (isPolyphonic && props.data?.status === PinYinStatus.Confirmed)
  );

  const onOpenChange = useMemoizedFn((isOpen: boolean) => {
    props.onClose && props.onClose();
    setMouseOpen(isOpen);
  });

  const activeItem = useMemoizedFn((idx: number) => {
    if ((props.data?.options && props.data.options.length <= 1) || isNaN(idx)) {
      return;
    }
    const targetItemDOM = document.querySelectorAll(
      `.${dropdownClassName} .ant-dropdown-menu-item`,
    )[idx];
    if (!targetItemDOM) return;
    targetItemDOM.classList.add("ant-dropdown-menu-item-active");
    const allItemDOM = document.querySelectorAll(
      ".ant-dropdown-menu-item-active",
    );
    allItemDOM.forEach(
      (dom) =>
        dom !== targetItemDOM &&
        dom.classList.remove("ant-dropdown-menu-item-active"),
    );
  });

  useEffect(() => {
    if (open) {
      activeItem(itemRealIdx);
    }
    if (isNew) {
      setIsNew(false);
      return;
    }
    onPinYinMarked();
  }, [itemRealIdx, open]);

  useEffect(() => {
    setItemRealIdx(props.itemIdx ?? 0);
  }, [props.itemIdx]);

  return isPolyphonic ? (
    <Dropdown
      overlayClassName={dropdownClassName}
      menu={{ items }}
      trigger={["click"]}
      open={open}
      onOpenChange={onOpenChange}
      placement={"bottom"}
      arrow
    >
      <Wrapper confirmed={+isConfirmed} multi={+isPolyphonic}>
        {value}
      </Wrapper>
    </Dropdown>
  ) : (
    <Wrapper confirmed={+isConfirmed} multi={+isPolyphonic}>
      {value}
    </Wrapper>
  );
}
